" 插件配置 {{{
    " 开启插件部分的 autocmd 组合
    augroup myplugins
    autocmd!

    " netrw
    " let loaded_netrwPlugin = 1
    let g:netrw_home=g:vimhome.'/tmp'

    " NERDCommenter {{{
        let g:NERDSpaceDelims = 1
        let g:NERDDefaultAlign = 'left'
        let g:NERDToggleCheckAllLines = 1
        let g:NERDCustomDelimiters = {'python': {'left': '#'}}
        let g:NERDToggleCheckAllLines = 1

        " vue文件的钩子，临时切换标签块中的文件类型
        let g:ft = ''
        function! NERDCommenter_before()
          if &filetype ==# 'vue'
            let g:ft = 'vue'
            let stack = synstack(line('.'), col('.'))
            if len(stack) > 0
              let syn = synIDattr((stack)[0], 'name')
              if len(syn) > 0
                exe 'setf ' . substitute(tolower(syn), '^vue_', '', '')
              endif
            endif
          endif
        endfunction
        function! NERDCommenter_after()
          if g:ft ==# 'vue'
            setf vue
            let g:ft = ''
          endif
        endfunction
    " }}}

    " delimitMate
    let delimitMate_expand_cr = 1
    set backspace=indent,eol,start

    if get(g:, 'file_explorer_plugin') ==# 'nerdtree' " {{{
        nnoremap <leader>nn :NERDTreeToggle<CR>

        " Start NERDTree when Vim starts with a directory argument.
        autocmd StdinReadPre * let s:std_in=1
        autocmd VimEnter * if argc() == 1 && isdirectory(argv()[0]) && !exists("s:std_in") | exe 'NERDTree' argv()[0] | wincmd p | ene | exe 'cd '.argv()[0] | wincmd h | endif

        " If another buffer tries to replace NERDTree, put it in the other window, and bring back NERDTree.
        autocmd BufRead * if bufname('#') =~ 'NERD_tree_\d\+' && bufname('%') !~ 'NERD_tree_\d\+' && winnr('$') > 1 |
                    \ let buf=bufnr('%') | buffer# | execute "normal! \<C-W>w" | execute 'buffer'.buf | endif
    " }}}
    elseif get(g:, 'file_explorer_plugin') ==# 'defx' " {{{
        nnoremap <leader>nd :Defx<CR>

        autocmd FileType defx call pg#defx#my_settings()
    " }}}
    elseif get(g:, 'file_explorer_plugin') ==# 'fern' " {{{
        let g:fern#disable_default_mappings = 1

        nnoremap <leader>nf :Fern . -drawer<CR>
        nnoremap - :Fern . -reveal=% -drawer<CR>

        autocmd FileType fern call pg#fern#init()
    endif " }}}

    " 添加一些常用的格式化对齐按键
    nnoremap <Leader>a= :Tabularize /=<CR>
    vnoremap <Leader>a= :Tabularize /=<CR>
    nnoremap <Leader>a\| :Tabularize /\|<CR>
    vnoremap <Leader>a\| :Tabularize /\|<CR>
    nnoremap <Leader>a: :Tabularize /:\zs<CR>
    vnoremap <Leader>a: :Tabularize /:\zs<CR>

    if !get(g:, 'loaded_completion_plugin') " {{{
        if get(g:, 'completion_plugin') ==# 'neocomplecache'
            " neocomplcache
            let g:neocomplcache_enable_at_startup = 1
            let g:neocomplcache_enable_smart_case = 1
            inoremap <expr><TAB>  pumvisible() ? "\<C-n>" : "\<TAB>"
            inoremap <expr><C-h>  neocomplcache#cancel_popup()

            " neosnippet
            imap <C-k>    <Plug>(neosnippet_expand_or_jump)
            smap <C-k>    <Plug>(neosnippet_expand_or_jump)
            xmap <C-k>    <Plug>(neosnippet_expand_target)
        elseif get(g:, 'completion_plugin') ==# 'ncm2'
            " enable ncm2 for all buffers
            autocmd BufEnter * call ncm2#enable_for_buffer()

            " IMPORTANT: :help Ncm2PopupOpen for more information
            set completeopt=noinsert,menuone,noselect

            " suppress the annoying 'match x of y', 'The only match' and 'Pattern not
            " found' messages
            set shortmess+=c

            " CTRL-C doesn't trigger the InsertLeave autocmd . map to <ESC> instead.
            inoremap <c-c> <ESC>

            " Use <TAB> to select the popup menu:
            inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
            inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
        elseif get(g:, 'completion_plugin') ==# 'coc.nvim'
            execute 'source '.g:vimhome.'/config/coc.vim'
        endif
    endif " }}}

    " ALE
    if !get(g:, 'disable_ale')
        nnoremap <leader>y :ALEToggle<cr>
    end

    " vim-markdown
    let g:vim_markdown_folding_style_pythonic = 1

    " tinymode {{{
        call tinymode#ModeMsg('winsize', '窗口模式模式：+/- 加或减窗口的高度；>/< 加或减窗口的宽度', 1)
        call tinymode#EnterMap('winsize', '<C-W>+', '+')
        call tinymode#EnterMap('winsize', '<C-W>-', '-')
        call tinymode#EnterMap('winsize', '<C-W>>', '>')
        call tinymode#EnterMap('winsize', '<C-W><', '<')
        call tinymode#Map('winsize', '+', 'wincmd +')
        call tinymode#Map('winsize', '-', 'wincmd -')
        call tinymode#Map('winsize', '>', 'wincmd >')
        call tinymode#Map('winsize', '<', 'wincmd <')

        " 使用 <C-Q> 按键绑定会出错
        call tinymode#ModeMsg('quickwindow', 'Quick Window 切换模式：n - 下一个；p - 上一个；o - 打开 QuickFix；c - 关闭 QuickFix；等等。', 1)
        call tinymode#EnterMap('quickwindow', '<leader>q')
        call tinymode#Map('quickwindow', 'f', 'cfirst')
        call tinymode#Map('quickwindow', 'l', 'clast')
        call tinymode#Map('quickwindow', 'n', 'cnext')
        call tinymode#Map('quickwindow', 'p', 'cprevious')
        call tinymode#Map('quickwindow', 'o', 'cwindow')
        call tinymode#Map('quickwindow', 'c', 'cwindow')

        call tinymode#ModeMsg('cursoradjust', '光标调整模式，可用命令：l, L, h, H', 1)
        call tinymode#EnterMap('cursoradjust', 'zl', 'l')
        call tinymode#EnterMap('cursoradjust', 'zL', 'L')
        call tinymode#EnterMap('cursoradjust', 'zh', 'h')
        call tinymode#EnterMap('cursoradjust', 'zH', 'H')
        call tinymode#Map('cursoradjust', 'l', 'normal! zl')
        call tinymode#Map('cursoradjust', 'L', 'normal! zL')
        call tinymode#Map('cursoradjust', 'h', 'normal! zh')
        call tinymode#Map('cursoradjust', 'H', 'normal! zH')
    " }}}

    " Example: set local options based on syntax
    function! OnChangeVueSyntax(syntax)
      echom 'Syntax is '.a:syntax
      if a:syntax == 'html'
        setlocal commentstring=<!--%s-->
        setlocal comments=s:<!--,m:\ \ \ \ ,e:-->
      elseif a:syntax =~ 'css'
        setlocal comments=s1:/*,mb:*,ex:*/ commentstring&
      else
        setlocal commentstring=//%s
        setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
      endif
    endfunction

    " 缩进线
    let g:indentLine_enabled = 0
    let g:indentLine_char_list = ['|', '¦', '┆', '┊']
    nnoremap <leader>ig :IndentLinesToggle<cr>

    " fcitx
    " openSuse 15.4 通过 Python3 的方式切换不支持，改用使用命令行的方式
    if executable('fcitx-remote')
        let g:fcitx5_remote = 'fcitx-remote'
    endif

    " 终止插件部分的 autocmd 组合
    augroup END
" }}}

" 基本配置 {{{
    " 设置缓存目录
    let &directory=g:vimhome.'/tmp//'

    " modeline
    set modeline
    set modelines=1

    " 缩进
    set autoindent
    set smartindent
    set shiftwidth=4     " `>`和`<`控制的长度
    "set tabstop=8       " <TAB>显示的长度，维持默认值8不变
    set softtabstop=4    " 按下<TAB>键的长度
    set expandtab        " 按下<TAB>后自动展开为空格。如果要输入TAB，需要Ctrl-V <TAB>。

    " 格式化和自动换行
    set whichwrap=b,s,<,>
    set linebreak
    " set showbreak=>>>>
    " 1. Format 的时候，支持在中文处断行；
    " 2. Join lines 时，中文间不添加空格；
    " 3. 连接行时删除注释前导符。
    set formatoptions+=mMj
    set formatoptions-=r

    " 搜索和匹配
    set ignorecase
    set infercase
    set smartcase
    set incsearch
    set hlsearch

    " 切换 paste mode
    set pastetoggle=<F2>

    " 状态栏
    set laststatus=2

    " 命令栏
    set showcmd

    " 输入右边括号时光标不临时跳转到左边括号
    set noshowmatch

    " 响应按键更快一点
    set timeout ttimeout timeoutlen=1000 ttimeoutlen=100
" }}}

" 按键映射 {{{
    " unmap all esc keys
    call utils#mappings#Unmaps('<Esc>')

    " 修改 cw 的原始语义
    nnoremap cw dwi

    " 执行上一条Ex命令
    nnoremap g. :<Up><CR>
    
    " vimrc 相关
    nnoremap <F5> :execute join(getbufline('%', 1, '$'), "\n")<cr>
    inoremap <F5> <esc>:execute join(getbufline('%', 1, '$'), "\n")<cr>a
    vnoremap <F5> :<c-u>@*<cr>
    nnoremap <leader>ev :vsplit $MYVIMRC<cr>
    nnoremap <leader>sv :source $MYVIMRC<cr>

    " 窗口
    nnoremap <C-W>6 <C-W>p
    nnoremap <C-W><C-6> <C-W>p

    " 添加行相关的复制粘贴（与系统剪贴板打交道）
    if executable('pbcopy') && executable('pbpaste')
        vnoremap <C-c><C-c> :write !pbcopy<CR><CR>
        nnoremap <C-c><C-c> :.write !pbcopy<CR><CR>
        nnoremap <C-c><C-v> :read !pbpaste<CR>
    elseif executable('xclip')
        vnoremap <C-c><C-c> :write !xclip -selection clipboard<CR><CR>
        nnoremap <C-c><C-c> :.write !xclip -selection clipboard<CR><CR>
        nnoremap <C-c><C-v> :read !xclip -selection clipboard -out<CR>
    elseif executable('xsel')
        vnoremap <C-c><C-c> :write !xsel -b<CR><CR>
        nnoremap <C-c><C-c> :.write !xsel -b<CR><CR>
        nnoremap <C-c><C-v> :read !xsel -b<CR>
    else
        echo 'Warning: 未在系统中发现命令行剪贴板程序，复制和粘贴命令未生效'
    endif

    " 通过 root 权限写入（https://unix.stackexchange.com/a/378119）
    cnoremap w!! execute 'silent! write !sudo tee % >/dev/null' <bar> edit!

    " 查找当前单词但不跳转
    nnoremap * m`:keepjumps normal! *``<cr>
" }}}

" 语言相关 {{{
    " 禁止HTML文件内渲染<i>、<b>标签的样式（不要在Markdown文件中禁止）
    " let g:html_no_rendering = 1

    augroup myfiletypes
        autocmd!

        autocmd BufNewFile,BufFilePre,BufRead *.md set filetype=markdown
        autocmd BufNewFile,BufFilePre,BufRead *.json.jbuilder set filetype=ruby
        autocmd BufNewFile,BufFilePre,BufRead .condarc set filetype=yaml
        autocmd BufNewFile,BufFilePre,BufRead coc-settings.json set filetype=jsonc

        autocmd FileType python setlocal nosmartindent
        autocmd FileType ruby setlocal sw=2 sts=2
        autocmd FileType html setlocal sw=2 sts=2
        autocmd FileType javascript setlocal sw=2 sts=2 nocindent
        autocmd FileType typescript setlocal sw=2 sts=2 nocindent
        autocmd FileType css setlocal sw=2 sts=2
        autocmd FileType scss setlocal sw=2 sts=2
        autocmd FileType json setlocal sw=2 sts=2
        autocmd FileType yaml setlocal sw=2 sts=2
        autocmd FileType vue setlocal sw=2 sts=2
                    \ | syntax sync fromstart
        autocmd FileType markdown setlocal foldlevel=6 nolinebreak
        autocmd FileType vim setlocal foldmethod=marker | normal zR
    augroup END
" }}}

" 用户自定义命令 {{{
    command! -nargs=? -complete=file CheckAnnotations call utils#checks#CheckAnnotations('<args>')
    command! -range=% -nargs=? InsertLineNumbers <line1>,<line2>call utils#inserts#InsertLineNumbers('<args>')
" }}}
